#ifndef DISCOVERYCLIENT_H
#define DISCOVERYCLIENT_H

#include <QObject>
#include <QTimer>
#include <QJsonObject>
#include <QJsonDocument>
#include <QEventLoop>
#include <QHash>
#include <QSet>
#include <functional>
#include <memory>
#include <thread>
#include <atomic>
#include <chrono>
#include <uv.h>

namespace Discovery {

struct DeviceDiscoveryInfo {
    QString ipAddress;
    int port;
    QString deviceType;
    QString manufacturer;
    QString model;
    QString status;
    QString webInterface;
    QString rtspUrl;
    QJsonObject additionalInfo;
    
    // 生成指定通道和码流类型的RTSP URL
    // channel: 通道号 (1, 2, 3...)
    // streamType: 0=主码流, 1=子码流
    QString getRtspUrl(int channel = 1, int streamType = 0) const {
        return QString("rtsp://%1:554/live/%2/%3").arg(ipAddress).arg(channel).arg(streamType);
    }
    
    // 获取主码流URL (通道1)
    QString getMainStreamUrl(int channel = 1) const {
        return getRtspUrl(channel, 0);
    }
    
    // 获取子码流URL (通道1) 
    QString getSubStreamUrl(int channel = 1) const {
        return getRtspUrl(channel, 1);
    }
};

class DiscoveryClient : public QObject
{
    Q_OBJECT

public:
    using DeviceFoundCallback = std::function<void(const DeviceDiscoveryInfo&)>;

    explicit DiscoveryClient(QObject *parent = nullptr);
    ~DiscoveryClient();

    static DiscoveryClient& instance();

    // 启动发现：timeoutSeconds 为超时时间，retryCount 为额外重发次数（0 表示只发一次）
    bool start(int timeoutSeconds = 5, const QString& networkInterface = QString(), int retryCount = 0);
    void stop();
    
    // 同步搜索设备，阻塞直到超时或停止
    QList<DeviceDiscoveryInfo> searchDevicesSync(int timeoutSeconds = 5, const QString& networkInterface = QString());

    int registerCallback(const DeviceFoundCallback& callback);
    void unregisterCallback(int handle);


signals:
    void deviceFound(const DeviceDiscoveryInfo& device);
    void discoveryFinished();
    void errorOccurred(const QString& error);

private:
    // LibUV事件循环
    void runLoop();
    void stopLoopHandles();
    void sendDiscoveryRequest();
    
    // LibUV静态回调函数
    static void onAllocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
    static void onUdpRecv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, 
                          const struct sockaddr* addr, unsigned flags);
    static void onUdpSend(uv_udp_send_t* req, int status);
    static void walkCallback(uv_handle_t* handle, void* arg);
    
    // 实例方法回调
    void handleUdpRecv(ssize_t nread, const uv_buf_t* buf, 
                       const struct sockaddr* addr, unsigned flags);
    
    // 协议解析方法
    void parseDiscoveryResponse(const QByteArray& data, const QString& senderIP, int senderPort);
    QString buildDiscoveryRequest();
    QString createJsonRpcRequest(const QString& id, const QString& method, const QJsonObject& params);
    bool parseHttpResponse(const QString& rawData, QString& headers, QString& body);

private:
    // LibUV相关成员
    uv_loop_t* m_loop;
    uv_udp_t m_udpHandle;
    uv_timer_t m_retryTimer;       // 定时重发发现请求
    struct sockaddr_in m_sendAddr;
    std::thread m_loopThread;
    std::atomic<bool> m_isRunning;
    
    // 配置和状态
    int m_timeoutSeconds;
    int m_retryCount;              // 发现请求重发次数
    std::chrono::steady_clock::time_point m_startTime; // 发现开始时间
    int m_sentCount;               // 已发送发现请求次数（含第一次）
    int m_nextCallbackId;
    QEventLoop* m_eventLoop;
    QString m_networkInterface;  // 指定的网络接口IP地址

    // 用于在单次扫描中对设备去重（按 IP）
    QSet<QString> m_seenDeviceIps;
    
    QHash<int, DeviceFoundCallback> m_callbacks;
    
    static const QString MULTICAST_ADDR;
    static const int DISCOVERY_PORT;
};

} // namespace Discovery

#endif // DISCOVERYCLIENT_H